/*
 * Copyright (c) 2008-2009 Ravenhearte Design
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'Ravenhearte Design' nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.ravenhearte.hardboild.assets;

import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.renderer.ColorRGBA;
import com.jme.scene.Geometry;
import com.jme.scene.Node;
import com.jme.scene.state.CullState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.WireframeState;
import com.jme.scene.state.RenderState.StateType;
import com.jme.system.DisplaySystem;
import com.radakan.jme.mxml.MaterialLoader;
import com.radakan.jme.mxml.OgreLoader;
import com.radakan.jme.mxml.anim.MeshAnimationController;
import com.radakan.jme.mxml.anim.OgreMesh;
import com.radakan.jme.mxml.test.TestMeshLoading;

public class NodeAsset {
	private String name;
	AssetType type;
	Node object;
	MeshAnimationController animControl;

	public enum AssetType {
		MODEL, OUTLINEDMODEL,
		ANIMATION, MAP
	}

	public NodeAsset(String name, AssetType type) {
		this.name = name;
		this.type = type;
		object = new Node(name);
	}
	
	public void load(String filename) {
        OgreLoader loader = new OgreLoader();
        MaterialLoader matLoader = new MaterialLoader();
		switch(type) {
		case MODEL:	        
	        try {
	            URL matURL = NodeAsset.class.getClassLoader().getResource("assets/art/models/"+filename+".material");
	            URL meshURL = NodeAsset.class.getClassLoader().getResource("assets/art/models/"+filename+".mesh.xml");
	            
	            if (matURL != null){
	                matLoader.load(matURL.openStream());
	                if (matLoader.getMaterials().size() > 0)
	                    loader.setMaterials(matLoader.getMaterials());
	            }
	            
	            object.attachChild((Node) loader.loadModel(meshURL));
	            
                if(object.getChild(0).getControllerCount() != 0) {
                	animControl = (MeshAnimationController) object.getChild(0).getController(0);
                	animControl.setAnimation("Stand");
                	animControl.setRepeatType(MeshAnimationController.RT_WRAP);
                }
	        } catch (IOException ex) {
	            Logger.getLogger(TestMeshLoading.class.getName()).log(Level.SEVERE, null, ex);
	        }
	        break;
		case OUTLINEDMODEL:
	        try {
	            URL matURL = NodeAsset.class.getClassLoader().getResource("assets/art/models/"+filename+".material");
	            URL meshURL = NodeAsset.class.getClassLoader().getResource("assets/art/models/"+filename+".mesh.xml");
	            
	            if (matURL != null){
	                matLoader.load(matURL.openStream());
	                if (matLoader.getMaterials().size() > 0)
	                    loader.setMaterials(matLoader.getMaterials());
	            }
	            
	            object.attachChild((Node) loader.loadModel(meshURL));	            
	            loader = new OgreLoader();
	            object.attachChild(outlineNode((Node) loader.loadModel(meshURL)));

                if(object.getChild(0).getControllerCount() > 0) {
                	animControl = (MeshAnimationController) object.getChild(0).getController(0);
                	object.getChild(1).clearControllers();
                	animControl.addMesh((OgreMesh)((Node) object.getChild(1)).getChild(0));
                	animControl.setAnimation("Stand");
                	animControl.setRepeatType(MeshAnimationController.RT_WRAP);
                }
	        } catch (IOException ex) {
	        }
	        break;
			
		}
	}
	
	public String getName(){
		return name;
	}
	
	public Node get() {
		return object;
	}
	
	public MeshAnimationController getAnim() {
		return animControl;
	}

    public static Node outlineNode(Node node) {
        CullState cs = DisplaySystem.getDisplaySystem().getRenderer().createCullState();
        cs.setCullFace(CullState.Face.Back);
        cs.setEnabled(true);

        WireframeState ws = DisplaySystem.getDisplaySystem().getRenderer().createWireframeState();
        ws.setLineWidth(3.0f);
        ws.setFace(WireframeState.Face.Front);
        ws.setEnabled(true);

        node.setRenderState(cs);
        node.setRenderState(ws);
        

		Geometry child = (Geometry)node.getChild(0);
		child.clearRenderState(StateType.Texture);
		child.setSolidColor(ColorRGBA.black);
        
        return node;
    }
}